package io.webfolder.cdp.channel;

import static io.undertow.websockets.client.WebSocketClient.connectionBuilder;
import static org.xnio.OptionMap.EMPTY;

import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;

import org.xnio.IoFuture;
import org.xnio.Xnio;
import org.xnio.XnioWorker;

import io.undertow.connector.ByteBufferPool;
import io.undertow.server.DefaultByteBufferPool;
import io.undertow.websockets.client.WebSocketClient.ConnectionBuilder;
import io.undertow.websockets.core.WebSocketChannel;
import io.webfolder.cdp.exception.CdpException;
import io.webfolder.cdp.session.MessageHandler;
import io.webfolder.cdp.session.SessionFactory;

public class UndertowWebSocketFactory implements ChannelFactory, AutoCloseable {

	private static final int DEFAULT_POOL_BUFFER_SIZE = 8192;

	private final XnioWorker worker;

	private final ByteBufferPool pool;

	public UndertowWebSocketFactory() {
		try {
			worker = Xnio.getInstance().createWorker(EMPTY);
		} catch (IllegalArgumentException | IOException e) {
			throw new CdpException(e);
		}
		pool = new DefaultByteBufferPool(false, DEFAULT_POOL_BUFFER_SIZE);
	}

	public UndertowWebSocketFactory(XnioWorker worker, ByteBufferPool pool) {
		this.worker = worker;
		this.pool = pool;
	}

	@Override
	public Channel createChannel(Connection connection, SessionFactory factory, MessageHandler handler) {
		String url = ((WebSocketConnection) connection).getUrl();
		URI uri;
		try {
			uri = new URI(url);
		} catch (URISyntaxException e) {
			throw new CdpException(e);
		}
		ConnectionBuilder builder = connectionBuilder(worker, pool, uri);
		IoFuture<WebSocketChannel> future = builder.connect();
		return new UndertowWebSocketChannel(future, factory, handler);
	}

	@Override
	public void close() {
		if (worker != null) {
			worker.shutdownNow();
		}
		if (pool != null) {
			pool.close();
		}
	}
}
